﻿using System.Collections;
using System.IO;
using System.Text;
using System.Xml;
using MPMovieCatalog.Domain;
using MPMovieCatalog.Util;

namespace MPMovieCatalog.Export
{
    public class TextExporter : Exporter
    {
        public TextExporter(ArrayList movies, string fileName, string encodingName, bool includeFieldNames, string delimiter, string qualifier, string lineBreak, ArrayList fields)
            : base(ResourceUtils.GetString("textExport", 18), movies, fileName)
        {
            EncodingName = encodingName;
            IncludeFieldNames = includeFieldNames;
            Delimiter = delimiter;
            Qualifier = qualifier;
            LineBreak = lineBreak;
            Fields = fields;
        }

        public string EncodingName { get; set; }
        public bool IncludeFieldNames { get; set; }
        public string Delimiter { get; set; }
        public string Qualifier { get; set; }
        public string LineBreak { get; set; }
        public ArrayList Fields { get; set; }

        protected override void Export()
        {
            StreamWriter sw = new StreamWriter(FileName, false, Encoding.GetEncoding(EncodingName));

            if (IncludeFieldNames)
            {
                StringBuilder sb = new StringBuilder();
                foreach (Field field in Fields)
                {
                    if (sb.Length > 0)
                    {
                        sb.Append(Delimiter);
                    }
                    sb.Append(field.DisplayName);
                }
                sw.WriteLine(sb.ToString());
            }

            int i = 0;
            foreach (MovieInfo movieInfo in Movies)
            {
                if (CancellationPending)
                {
                    IsCancelled = true;
                    break;
                }
                else
                {
                    OnProgress(++i);

                    StringBuilder sb = new StringBuilder();
                    foreach (Field field in Fields)
                    {
                        if (sb.Length > 0)
                        {
                            sb.Append(Delimiter);
                        }
                        string value = GetFieldValue(movieInfo, field);
                        sb.Append(string.Format("{0}{1}{0}", Qualifier, value));
                    }
                    sw.WriteLine(sb.ToString());
                }
            }
            sw.Close();
        }

        private string GetFieldValue(MovieInfo movieInfo, Field field)
        {
            string value = "";
            XmlDocument movieXML = movieInfo.ToXML();
            if (field is SimpleField)
            {
                XmlNode node = movieXML.SelectSingleNode(string.Format("//movieInfo/{0}", field.Name));
                if (node != null && node.FirstChild != null)
                {
                    value = node.FirstChild.Value;
                }
            }
            else if (field is ListField)
            {
                StringBuilder sb = new StringBuilder();
                foreach (XmlNode node in movieXML.SelectNodes(string.Format("//movieInfo/{0}/{1}", field.Name, ((ListField)field).SingularName)))
                {
                    if (sb.Length > 0)
                    {
                        sb.Append("; ");
                    }
                    sb.Append(node.FirstChild.Value);
                }
                value = sb.ToString();
            }
            return ReplaceLineBreaks(value);
        }

        private string ReplaceLineBreaks(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                return str.Replace("\n", LineBreak);
            }
            return str;
        }
    }
}
